use std::collections::VecDeque;
use std::cell::RefCell;
use super::{MonitorHandle, WindowId, ActiveEventLoop, OsError};
use crate::window::{
    ActivationToken, Cursor, CursorGrabMode, CustomCursor, CustomCursorSource, ImePurpose,
    ResizeDirection, Theme, UserAttentionType, WindowAttributes, WindowButtons, WindowLevel,
};
use crate::event_loop::AsyncRequestSerial;
use crate::error::{EventLoopError, ExternalError, NotSupportedError, OsError as RootOsError};
pub(crate) use crate::platform_impl::Fullscreen;
use crate::icon::Icon;
use crate::dpi::{PhysicalPosition, PhysicalSize, Position, Size};

pub struct Window {
    title: RefCell<String>,
    // /// Reference to the underlying SCTK window.
    // window: SctkWindow,

    /// Window id.
    window_id: WindowId,

    // /// The state of the window.
    // window_state: Arc<Mutex<WindowState>>,

    // /// Compositor to handle WlRegion stuff.
    // compositor: Arc<CompositorState>,

    // /// The wayland display used solely for raw window handle.
    // #[allow(dead_code)]
    // display: WlDisplay,

    // /// Xdg activation to request user attention.
    // xdg_activation: Option<XdgActivationV1>,

    // /// The state of the requested attention from the `xdg_activation`.
    // attention_requested: Arc<AtomicBool>,

    // /// Handle to the main queue to perform requests.
    // queue_handle: QueueHandle<WinitState>,

    // /// Window requests to the event loop.
    // window_requests: Arc<WindowRequests>,

    // /// Observed monitors.
    // monitors: Arc<Mutex<Vec<MonitorHandle>>>,

    // /// Source to wake-up the event-loop for window requests.
    // event_loop_awakener: calloop::ping::Ping,

    // /// The event sink to deliver synthetic events.
    // window_events_sink: Arc<Mutex<EventSink>>,
}

impl Window {
    #[inline]
    pub(crate) fn new(
        window_target: &ActiveEventLoop,
        attribs: WindowAttributes,
    ) -> Result<Self, RootOsError> {
        Err(os_error!(OsError::Misc("Not implemented")))
    }

    pub(crate) fn maybe_queue_on_main(&self, f: impl FnOnce(&Self) + Send + 'static) {
        f(self)
    }

    pub(crate) fn maybe_wait_on_main<R: Send>(&self, f: impl FnOnce(&Self) -> R + Send) -> R {
        f(self)
    }

    #[inline]
    pub fn id(&self) -> WindowId {
        self.window_id
    }

    #[inline]
    pub fn set_title(&self, title: &str) {
        *self.title.borrow_mut() = title.to_string();
    }

    #[inline]
    pub fn set_transparent(&self, transparent: bool) {
    }

    #[inline]
    pub fn set_blur(&self, blur: bool) {
    }

    #[inline]
    pub fn set_visible(&self, visible: bool) {
    }

    #[inline]
    pub fn is_visible(&self) -> Option<bool> {
        None
    }

    #[inline]
    pub fn outer_position(&self) -> Result<PhysicalPosition<i32>, NotSupportedError> {
        Err(NotSupportedError::new())
    }

    #[inline]
    pub fn inner_position(&self) -> Result<PhysicalPosition<i32>, NotSupportedError> {
        Err(NotSupportedError::new())
    }

    #[inline]
    pub fn set_outer_position(&self, position: Position) {
    }

    #[inline]
    pub fn inner_size(&self) -> PhysicalSize<u32> {
        PhysicalSize::new(0, 0)
    }

    #[inline]
    pub fn outer_size(&self) -> PhysicalSize<u32> {
        PhysicalSize::new(0, 0)
    }

    #[inline]
    pub fn request_inner_size(&self, size: Size) -> Option<PhysicalSize<u32>> {
        None
    }

    #[inline]
    pub(crate) fn request_activation_token(&self) -> Result<AsyncRequestSerial, NotSupportedError> {
        Err(NotSupportedError::new())
    }

    #[inline]
    pub fn set_min_inner_size(&self, dimensions: Option<Size>) {
    }

    #[inline]
    pub fn set_max_inner_size(&self, dimensions: Option<Size>) {
        
    }

    #[inline]
    pub fn resize_increments(&self) -> Option<PhysicalSize<u32>> {
        None
    }

    #[inline]
    pub fn set_resize_increments(&self, increments: Option<Size>) {
        
    }

    #[inline]
    pub fn set_resizable(&self, resizable: bool) {
        
    }

    #[inline]
    pub fn is_resizable(&self) -> bool {
        false
    }

    #[inline]
    pub fn set_enabled_buttons(&self, buttons: WindowButtons) {
        
    }

    #[inline]
    pub fn enabled_buttons(&self) -> WindowButtons {
        WindowButtons::empty()
    }

    #[inline]
    pub fn set_cursor(&self, cursor: Cursor) {
        
    }

    #[inline]
    pub fn set_cursor_grab(&self, mode: CursorGrabMode) -> Result<(), ExternalError> {
        Err(ExternalError::NotSupported(NotSupportedError::new()))
    }

    #[inline]
    pub fn set_cursor_visible(&self, visible: bool) {
        
    }

    #[inline]
    pub fn drag_window(&self) -> Result<(), ExternalError> {
        Err(ExternalError::NotSupported(NotSupportedError::new()))
    }

    #[inline]
    pub fn drag_resize_window(&self, direction: ResizeDirection) -> Result<(), ExternalError> {
        Err(ExternalError::NotSupported(NotSupportedError::new()))
    }

    #[inline]
    pub fn show_window_menu(&self, position: Position) {
        
    }

    #[inline]
    pub fn set_cursor_hittest(&self, hittest: bool) -> Result<(), ExternalError> {
        Err(ExternalError::NotSupported(NotSupportedError::new()))
    }

    #[inline]
    pub fn scale_factor(&self) -> f64 {
        0.0
    }

    #[inline]
    pub fn set_cursor_position(&self, position: Position) -> Result<(), ExternalError> {
        Err(ExternalError::NotSupported(NotSupportedError::new()))
    }

    #[inline]
    pub fn set_maximized(&self, maximized: bool) {
        
    }

    #[inline]
    pub fn is_maximized(&self) -> bool {
        false
    }

    #[inline]
    pub fn set_minimized(&self, minimized: bool) {
        
    }

    #[inline]
    pub fn is_minimized(&self) -> Option<bool> {
        None
    }

    #[inline]
    pub(crate) fn fullscreen(&self) -> Option<Fullscreen> {
        None
    }

    #[inline]
    pub(crate) fn set_fullscreen(&self, monitor: Option<Fullscreen>) {
    }

    #[inline]
    pub fn set_decorations(&self, decorations: bool) {
        
    }

    #[inline]
    pub fn is_decorated(&self) -> bool {
        false
    }

    #[inline]
    pub fn set_window_level(&self, level: WindowLevel) {
        
    }

    #[inline]
    pub fn set_window_icon(&self, window_icon: Option<Icon>) {
    }

    #[inline]
    pub fn set_ime_cursor_area(&self, position: Position, size: Size) {
    }

    #[inline]
    pub fn reset_dead_keys(&self) {
    }

    #[inline]
    pub fn set_ime_allowed(&self, allowed: bool) {
    }

    #[inline]
    pub fn set_ime_purpose(&self, purpose: ImePurpose) {
    }

    #[inline]
    pub fn focus_window(&self) {
    }

    pub fn request_user_attention(&self, request_type: Option<UserAttentionType>) {
    }

    #[inline]
    pub fn request_redraw(&self) {
    }

    #[inline]
    pub fn pre_present_notify(&self) {
    }

    #[inline]
    pub fn current_monitor(&self) -> Option<MonitorHandle> {
        None
    }

    #[inline]
    pub fn available_monitors(&self) -> VecDeque<MonitorHandle> {
        VecDeque::new()
    }

    #[inline]
    pub fn primary_monitor(&self) -> Option<MonitorHandle> {
        None
    }

    // #[cfg(feature = "rwh_04")]
    // #[inline]
    // pub fn raw_window_handle_rwh_04(&self) -> rwh_04::RawWindowHandle {

    // }

    // #[cfg(feature = "rwh_05")]
    // #[inline]
    // pub fn raw_window_handle_rwh_05(&self) -> rwh_05::RawWindowHandle {
    // }

    // #[cfg(feature = "rwh_05")]
    // #[inline]
    // pub fn raw_display_handle_rwh_05(&self) -> rwh_05::RawDisplayHandle {
    // }

    // #[cfg(feature = "rwh_06")]
    // #[inline]
    // pub fn raw_window_handle_rwh_06(&self) -> Result<rwh_06::RawWindowHandle, rwh_06::HandleError> {
    // }

    // #[cfg(feature = "rwh_06")]
    // #[inline]
    // pub fn raw_display_handle_rwh_06(
    //     &self,
    // ) -> Result<rwh_06::RawDisplayHandle, rwh_06::HandleError> {
    // }

    #[inline]
    pub fn set_theme(&self, theme: Option<Theme>) {
    }

    #[inline]
    pub fn theme(&self) -> Option<Theme> {
        None
    }

    pub fn set_content_protected(&self, protected: bool) {
    }

    #[inline]
    pub fn has_focus(&self) -> bool {
        false
    }

    pub fn title(&self) -> String {
        self.title.borrow().clone()
    }
}

impl Drop for Window {
    fn drop(&mut self) {
    }
}